use std::fs;

use dirs::home_dir;

use include_dir::{include_dir, Dir};
use rbatis::RBatis;
use rbdc_sqlite::driver::SqliteDriver;

use crate::{CONFIG_FILE_NAME, CONTEXT, DATA_ROOT, DB_FILE_NAME};

static DATA_DIR: Dir = include_dir!("data");

#[derive(Debug, serde::Serialize, serde::Deserialize, Default)]
pub struct AppConfig {
    pub server_url: String,
}
pub fn init_config() -> (AppConfig, RBatis) {
    let mut home_dir = home_dir().unwrap();
    home_dir.push(DATA_ROOT);
    if !home_dir.exists() {
        DATA_DIR.extract(home_dir.clone()).unwrap();
    }

    let mut config = home_dir.clone();
    config.push(CONFIG_FILE_NAME);
    let json = fs::read_to_string(config).expect("##read config.json err");
    let config = serde_json::from_str::<AppConfig>(json.as_str()).expect("##parse config.json err");
    home_dir.push(DB_FILE_NAME);
    let rb = rbatis::RBatis::new();
    rb.init(
        SqliteDriver {},
        &format!("sqlite://{}", home_dir.to_str().unwrap())[..],
    )
    .expect("open sqlite err");
    log::info!("[blog] rbatis init success");
    (config, rb)
}

#[derive(Debug, Default)]
pub struct AppContext {
    pub config: AppConfig,
    pub rb: RBatis,
}
impl AppContext {
    pub fn config() -> &'static AppConfig {
        &CONTEXT.config
    }

    pub fn rbatis() -> &'static RBatis {
        &CONTEXT.rb
    }
}
